<?php

class RSCharacter implements ArrayAccess
{
	private $name;
	private $isLoaded;
	private $records;

	public function __construct ($name)
	{
		$this->name = rshl_get_raw_name($name);
		$this->isLoaded = false;
		$this->records = array();
	}

	public function load ($reload = false)
	{
		if ($this->isLoaded && !$reload)
		{
			return false;
		}

		$this->records = RSHiLib::loadCharacter($this->name, $reload);
		$this->isLoaded = true;

		return true;
	}

	public function getRank ($record)
	{
		$this->load();
		$record = RSRecordList::getRecord($record);
		return $this->records[$record['key']]['rank'];
	}

	public function getLevel ($skill)
	{
		$this->load();
		$skill = RSRecordList::getSkill($skill);
		return $this->records[$skill['key']]['level'];
	}

	public function getXP ($skill)
	{
		$this->load();
		$skill = RSRecordList::getSkill($skill);
		return $this->records[$skill['key']]['xp'];
	}

	public function getScore ($activity)
	{
		$this->load();
		$activity = RSRecordList::getActivity($activity);
		return $this->records[$activity['key']]['score'];
	}

	public function __set ($name, $value)
	{
		$name = $this->verifyRecordName($name);
		$info = RSRecordList::getRecord($name);

		switch ($info['type'])
		{
			case RSRecordList::TYPE_SKILL:
				$class = 'RSSkillRecord';
				break;

			case RSRecordList::TYPE_ACTIVITY:
				$class = 'RSActivityRecord';
				break;

			default:
				throw new RSHiLibRuntimeException("Unknown record type");
		}

		if (!($value instanceof $class))
		{
			throw new InvalidRecordValueException("Invalid record value");
		}

		$this->records[$name] = $value->getValues();
	}

	public function __get ($name)
	{
		$name = $this->verifyRecordName($name);
		$info = RSRecordList::getRecord($name);

		switch ($info['type'])
		{
			case RSRecordList::TYPE_SKILL:
				$record = new RSKillRecord($this->records[$name], $this);
				break;

			case RSRecordList::TYPE_ACTIVITY:
				$record = new RSActivityRecord($this->records[$name], $this);
				break;

			default:
				throw new RSHiLibRuntimeException("Unknown record type");
		}

		return $record;
	}

	public function __isset ($name)
	{
		try
		{
			$this->verifyRecordName($name);
		}
		catch (InvalidRecordException $ex)
		{
			return false;
		}

		return true;
	}

	public function __unset ($name)
	{
		$name = $this->verifyRecordName($name);
		$info = RSRecordList::getRecord($name);

		switch ($info['type'])
		{
			case RSRecordList::TYPE_SKILL:
				$record = array('rank' => -1, 'level' => -1, 'xp' => -1);
				break;

			case RSRecordList::TYPE_ACTIVITY:
				$record = array('rank' => -1, 'score' => -1);
				break;

			default:
				throw new RSHiLibRuntimeException("Unknown record type");
		}

		$this->records[$name] = $record;
	}

	private function verifyRecordName ($name)
	{
		$this->load();

		if (!isset($this->records[$name]))
		{
			throw new InvalidRecordException("'$name' is not a valid character record");
		}

		return $name;
	}

	public function offsetExists ($offset)
	{
		return $this->__isset($offset);
	}

	public function offsetGet ($offset)
	{
		return $this->__get($offset);
	}

	public function offsetSet ($offset, $value)
	{
		$this->__set($offset, $value);
	}

	public function offsetUnset ($offset)
	{
		$this->__unset($offset);
	}

	public function getHTMLName ()
	{
		return rshl_get_html_name($this->name);
	}

	public function __toString ()
	{
		return rshl_get_formatted_name($this->name);
	}
}